﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using BitmapTagger;
using System.IO;

using ImageTagEditor.ValueConverters;
using ImageTagEditor.ValidationRules;
using ImageTagEditor.Properties;

namespace ImageTagEditor
{
	/// <summary>
	/// Interaction logic for ImageTagView.xaml
	/// </summary>
	public partial class ImageTagView : UserControl
	{
		#region value converters

		/// <summary>
		/// The value converter to use for rationals to text boxes
		/// </summary>
		private RationalValueConverter rationalValueConverter;

		/// <summary>
		/// The value converter to use for urationals to text boxes
		/// </summary>
		private URationalValueConverter urationalValueConverter;

		/// <summary>
		/// The value converter to use for the resolution unit to text boxes
		/// </summary>
		private ResolutionUnitValueConverter resolutionUnitValueConverter;

		/// <summary>
		/// The value converter to use for float? to text boxes
		/// </summary>
		private NullableFloatValueConverter nullableFloatValueConverter;

		/// <summary>
		/// The value converter to use for plain string to normalize "" and null
		/// </summary>
		private StringNullValueConverter stringNullValueConverter;

		/// <summary>
		/// The value converter to use for ushort? to text boxes
		/// </summary>
		private NullableUShortValueConverter nullableUshortValueConverter;

		/// <summary>
		/// The value converter to use for the metering mode
		/// </summary>
		private MeteringModeValueConverter meteringModeValueConverter;

		/// <summary>
		/// The value converter to use for the exposure program
		/// </summary>
		private ExposureProgramValueConverter exposureProgramValueConverter;

		/// <summary>
		/// The value converter to use for the light source
		/// </summary>
		private LightSourceValueConverter lightSourceValueConverter;

		/// <summary>
		/// The value converter to use for the sensing method
		/// </summary>
		private SensingMethodValueConverter sensingMethodValueConverter;

		#endregion

		#region validation rules

		/// <summary>
		/// The validaiton rule to check that strings are in valid rational formats
		/// </summary>
		private RationalValidationRule rationalValidationRule;

		/// <summary>
		/// The validation rule to check that strings are in valid urational formats
		/// </summary>
		private URationalValidationRule urationalValidationRule;

		#endregion


		/// <summary>
		/// The Error to use for invalid format 
		/// </summary>
		private const string INVALID_FORM_ERROR = "The value for this tag is not in a valid format.";

		/// <summary>
		/// Create a new Image Tag View
		/// </summary>
		public ImageTagView()
		{
			InitializeComponent();
		}

		/// <summary>
		/// Show the image for the current bitmap tagger
		/// </summary>
		public void ShowImage()
		{
			//this.image.Source = new BitmapImage(new Uri(Tagger.FilePath));
			//show the Image
			using (Stream stream = File.Open(Tagger.FilePath, FileMode.Open))
			{
				BitmapDecoder decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
				image.Source = decoder.Frames[0];
			}
		}

		/// <summary>
		/// Create a new Image Tag View
		/// </summary>
		/// <param name="tagger">The ImageTagger this view is to display</param>
		public ImageTagView(BitmapTagger.BitmapTagger tagger)
		{
			Tagger = new ObservableBitmapTagger(tagger);
			InitializeComponent();
			
		}

		/// <summary>
		/// The bitmap tagger this image tag view is displaying
		/// </summary>
		private ObservableBitmapTagger tagger; 

		/// <summary>
		/// Get or set the bitmap tagger
		/// </summary>
		public ObservableBitmapTagger Tagger
		{
			get
			{
				return tagger;
			}
			set
			{
				if(tagger != null)
					RemoveBindings();

				tagger = value;

				if (tagger != null)
				{
					RemoveBindings();
					SetBindings();
				}
			}
		}


		/// <summary>
		/// Update the displaying file path
		/// </summary>
		/// <remarks>
		/// Call after a save as
		/// </remarks>
		public void UpdateFilePath()
		{
			filePathTextBox.Text = Tagger.FilePath;
		}


		#region set and remove bindings

		/// <summary>
		/// Set the bindings from the tagger to the UI elements
		/// </summary>
		private void SetBindings()
		{
			rationalValueConverter = new RationalValueConverter();
			urationalValueConverter = new URationalValueConverter();
		    resolutionUnitValueConverter = new ResolutionUnitValueConverter();
			nullableFloatValueConverter = new NullableFloatValueConverter();
			stringNullValueConverter = new StringNullValueConverter();
			meteringModeValueConverter = new MeteringModeValueConverter();
			exposureProgramValueConverter = new ExposureProgramValueConverter();
			nullableUshortValueConverter = new NullableUShortValueConverter();
			lightSourceValueConverter = new LightSourceValueConverter();
			sensingMethodValueConverter = new SensingMethodValueConverter();

			rationalValidationRule = new RationalValidationRule();
			urationalValidationRule = new URationalValidationRule();


			//General bindings
			filePathTextBox.Text = Tagger.FilePath;
			pixelHeightTextBox.Text = Tagger.ImageHeight.ToString();
			pixelWidthTextBox.Text = Tagger.ImageWidth.ToString();

			xResolutionTextBox.Text = (string)urationalValueConverter.Convert(Tagger.XResolution, null, null, null);
			yResolutionTextBox.Text = (string)urationalValueConverter.Convert(Tagger.YResolution, null, null, null);

			resolutionUnitTextBox.Text = (string)resolutionUnitValueConverter.Convert(Tagger.ResolutionUnit, null, null, null);
			unitHeightTextBox.Text = (string)nullableFloatValueConverter.Convert(Tagger.UnitHeight, null, null, null);
			unitWidthTextBox.Text = (string)nullableFloatValueConverter.Convert(Tagger.UnitWidth, null, null, null);


			Binding bind;

			//Description bindings
			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("ImageDescription");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			bind.Converter = stringNullValueConverter;
			imageDescriptionTextBox.SetBinding(TextBox.TextProperty, bind);


			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("Make");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			bind.Converter = stringNullValueConverter;
			makeTextBox.SetBinding(TextBox.TextProperty, bind);

			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("Model");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			bind.Converter = stringNullValueConverter;
			modelTextBox.SetBinding(TextBox.TextProperty, bind);

			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("Software");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			bind.Converter = stringNullValueConverter;
			softwareTextBox.SetBinding(TextBox.TextProperty, bind);

			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("Artist");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			bind.Converter = stringNullValueConverter;
			artistTextBox.SetBinding(TextBox.TextProperty, bind);

			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("Copyright");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			bind.Converter = stringNullValueConverter;
			copyrightTextBox.SetBinding(TextBox.TextProperty, bind);

			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("UserComment");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			bind.Converter = stringNullValueConverter;
			userCommentTextBox.SetBinding(TextBox.TextProperty, bind);


			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("MakerNote");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			bind.Converter = stringNullValueConverter;
			makerNoteTextBox.SetBinding(TextBox.TextProperty, bind);


			//DateTime binding
			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("DateTime");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			dateTimeDateTimePicker.SetBinding(NullableDateTimePicker.DateTimeProperty, bind);

			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("DateTimeOriginal");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			dateTimeOriginalDateTimePicker.SetBinding(NullableDateTimePicker.DateTimeProperty, bind);

			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("DateTimeDigitized");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			dateTimeDigitizedDateTimePicker.SetBinding(NullableDateTimePicker.DateTimeProperty, bind);

			//Picture Taking Conditions
			
			foreach (string definition in meteringModeValueConverter.Definitions)
				meteringModeComboBox.Items.Add(definition);
			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("MeteringMode");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			bind.Converter = meteringModeValueConverter;
			meteringModeComboBox.SetBinding(ComboBox.SelectedItemProperty, bind);

			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("ExposureTime");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
			bind.Converter = urationalValueConverter;
			bind.ValidationRules.Add(urationalValidationRule);
			bind.NotifyOnValidationError = true;
			exposureTimeTextBox.SetBinding(TextBox.TextProperty, bind);

			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("FNumber");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
			bind.Converter = urationalValueConverter;
			bind.ValidationRules.Add(urationalValidationRule);
			bind.NotifyOnValidationError = true;
			fNumberTextBox.SetBinding(TextBox.TextProperty, bind);


			foreach (string definition in exposureProgramValueConverter.Definitions)
				exposureProgramComboBox.Items.Add(definition);
			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("ExposureProgram");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			bind.Converter = exposureProgramValueConverter;
			exposureProgramComboBox.SetBinding(ComboBox.SelectedItemProperty, bind);

			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("ISOSpeedRatings");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
			bind.Converter = nullableUshortValueConverter;
			isoSpeedRatingsTextBox.SetBinding(TextBox.TextProperty, bind);
			isoSpeedRatingsTextBox.MaxValue = ushort.MaxValue;
			isoSpeedRatingsTextBox.MinValue = ushort.MinValue;

			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("ShutterSpeed");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
			bind.Converter = rationalValueConverter;
			bind.ValidationRules.Add(rationalValidationRule);
			bind.NotifyOnValidationError = true;
			shutterSpeedTextBox.SetBinding(TextBox.TextProperty, bind);

			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("Aperture");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
			bind.Converter = urationalValueConverter;
			bind.ValidationRules.Add(urationalValidationRule);
			bind.NotifyOnValidationError = true;
			apertureTextBox.SetBinding(TextBox.TextProperty, bind);

			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("Brightness");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
			bind.Converter = rationalValueConverter;
			bind.ValidationRules.Add(rationalValidationRule);
			bind.NotifyOnValidationError = true;
			brightnessTextBox.SetBinding(TextBox.TextProperty, bind);

			foreach (string definition in lightSourceValueConverter.Definitions)
				lightSourceComboBox.Items.Add(definition);
			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("LightSource");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			bind.Converter = lightSourceValueConverter;
			lightSourceComboBox.SetBinding(ComboBox.SelectedItemProperty, bind);

			foreach (string definition in sensingMethodValueConverter.Definitions)
				sensingMethodComboBox.Items.Add(definition);
			bind = new Binding();
			bind.Source = Tagger;
			bind.Path = new PropertyPath("SensingMethod");
			bind.Mode = BindingMode.TwoWay;
			bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			bind.Converter = sensingMethodValueConverter;
			sensingMethodComboBox.SetBinding(ComboBox.SelectedItemProperty, bind);
		}

		/// <summary>
		/// Remove the bindings from this view to the bitmap tagger
		/// </summary>
		private void RemoveBindings()
		{
			//General bindings
			filePathTextBox.Text = "";
			pixelHeightTextBox.Text = "";
			pixelWidthTextBox.Text = "";

			xResolutionTextBox.Text = "";
			yResolutionTextBox.Text = "";

			resolutionUnitTextBox.Text = "";
			unitHeightTextBox.Text = "";
			unitWidthTextBox.Text = "";




			//Description bindings
			if (BindingOperations.IsDataBound(imageDescriptionTextBox, TextBox.TextProperty))
				BindingOperations.ClearBinding(imageDescriptionTextBox, TextBox.TextProperty);

			if (BindingOperations.IsDataBound(makeTextBox, TextBox.TextProperty))
				BindingOperations.ClearBinding(makeTextBox, TextBox.TextProperty);

			if (BindingOperations.IsDataBound(modelTextBox, TextBox.TextProperty))
				BindingOperations.ClearBinding(modelTextBox, TextBox.TextProperty);

			if (BindingOperations.IsDataBound(softwareTextBox, TextBox.TextProperty))
				BindingOperations.ClearBinding(softwareTextBox, TextBox.TextProperty);

			if (BindingOperations.IsDataBound(artistTextBox, TextBox.TextProperty))
				BindingOperations.ClearBinding(artistTextBox, TextBox.TextProperty);

			if (BindingOperations.IsDataBound(copyrightTextBox, TextBox.TextProperty))
				BindingOperations.ClearBinding(copyrightTextBox, TextBox.TextProperty);

			if (BindingOperations.IsDataBound(userCommentTextBox, TextBox.TextProperty))
				BindingOperations.ClearBinding(userCommentTextBox, TextBox.TextProperty);

			if (BindingOperations.IsDataBound(makerNoteTextBox, TextBox.TextProperty))
				BindingOperations.ClearBinding(makerNoteTextBox, TextBox.TextProperty);


			//DateTime binding
			if (BindingOperations.IsDataBound(dateTimeDateTimePicker, NullableDateTimePicker.DateTimeProperty))
				BindingOperations.ClearBinding(dateTimeDateTimePicker, NullableDateTimePicker.DateTimeProperty);

			if (BindingOperations.IsDataBound(dateTimeOriginalDateTimePicker, NullableDateTimePicker.DateTimeProperty))
				BindingOperations.ClearBinding(dateTimeOriginalDateTimePicker, NullableDateTimePicker.DateTimeProperty);

			if (BindingOperations.IsDataBound(dateTimeOriginalDateTimePicker, NullableDateTimePicker.DateTimeProperty))
				BindingOperations.ClearBinding(dateTimeOriginalDateTimePicker, NullableDateTimePicker.DateTimeProperty);


			//Picture Taking Conditions
			if (BindingOperations.IsDataBound(meteringModeComboBox, ComboBox.SelectedItemProperty))
				BindingOperations.ClearBinding(meteringModeComboBox, ComboBox.SelectedItemProperty);
			meteringModeComboBox.Items.Clear();
			


			if (BindingOperations.IsDataBound(exposureTimeTextBox, TextBox.TextProperty))
				BindingOperations.ClearBinding(exposureTimeTextBox, TextBox.TextProperty);

			
			if (BindingOperations.IsDataBound(fNumberTextBox, TextBox.TextProperty))
				BindingOperations.ClearBinding(fNumberTextBox, TextBox.TextProperty);


			if (BindingOperations.IsDataBound(exposureProgramComboBox, ComboBox.SelectedItemProperty))
				BindingOperations.ClearBinding(exposureProgramComboBox, ComboBox.SelectedItemProperty);
			exposureProgramComboBox.Items.Clear();
			

			if (BindingOperations.IsDataBound(isoSpeedRatingsTextBox, TextBox.TextProperty))
				BindingOperations.ClearBinding(isoSpeedRatingsTextBox, TextBox.TextProperty);


			if (BindingOperations.IsDataBound(shutterSpeedTextBox, TextBox.TextProperty))
				BindingOperations.ClearBinding(shutterSpeedTextBox, TextBox.TextProperty);

			if (BindingOperations.IsDataBound(apertureTextBox, TextBox.TextProperty))
				BindingOperations.ClearBinding(apertureTextBox, TextBox.TextProperty);

			if (BindingOperations.IsDataBound(brightnessTextBox, TextBox.TextProperty))
				BindingOperations.ClearBinding(brightnessTextBox, TextBox.TextProperty);

			if (BindingOperations.IsDataBound(lightSourceComboBox, ComboBox.SelectedItemProperty))
				BindingOperations.ClearBinding(lightSourceComboBox, ComboBox.SelectedItemProperty);
			lightSourceComboBox.Items.Clear();

			if (BindingOperations.IsDataBound(sensingMethodComboBox, ComboBox.SelectedItemProperty))
				BindingOperations.ClearBinding(sensingMethodComboBox, ComboBox.SelectedItemProperty);
			sensingMethodComboBox.Items.Clear();
			

		}

		#endregion


		#region validation error listeners

		/// <summary>
		/// Listens for when a the error state of exposureTimeTextBox changed
		/// </summary>
		/// <param name="sender">Not Used</param>
		/// <param name="e">The event arguments of the error state change</param>
		private void exposureTimeTextBox_Error(object sender, ValidationErrorEventArgs e)
		{
			if (Validation.GetHasError(exposureTimeTextBox))
				exposureTimePowerToolTip.Error = INVALID_FORM_ERROR;
			else
				exposureTimePowerToolTip.Error = "";
		}

		/// <summary>
		/// Listens for when a the error state of fNumberTextBox changed
		/// </summary>
		/// <param name="sender">Not Used</param>
		/// <param name="e">The event arguments of the error state change</param>
		private void fNumberTextBox_Error(object sender, ValidationErrorEventArgs e)
		{
			if (Validation.GetHasError(fNumberTextBox))
				fNumberPowerToolTip.Error = INVALID_FORM_ERROR;
			else
				fNumberPowerToolTip.Error = "";
		}

		/// <summary>
		/// Listens for when a the error state of brightnessTextBox changed
		/// </summary>
		/// <param name="sender">Not Used</param>
		/// <param name="e">The event arguments of the error state change</param>
		private void brightnessTextBox_Error(object sender, ValidationErrorEventArgs e)
		{
			if (Validation.GetHasError(brightnessTextBox))
				brightnessPowerToolTip.Error = INVALID_FORM_ERROR;
			else
				brightnessPowerToolTip.Error = "";
		}

		/// <summary>
		/// Listens for when a the error state of apertureTextBox changed
		/// </summary>
		/// <param name="sender">Not Used</param>
		/// <param name="e">The event arguments of the error state change</param>
		private void apertureTextBox_Error(object sender, ValidationErrorEventArgs e)
		{
			if (Validation.GetHasError(apertureTextBox))
				aperturePowerToolTip.Error = INVALID_FORM_ERROR;
			else
				aperturePowerToolTip.Error = "";
		}

		/// <summary>
		/// Listens for when a the error state of shutterSpeedTextBox changed
		/// </summary>
		/// <param name="sender">Not Used</param>
		/// <param name="e">The event arguments of the error state change</param>
		private void shutterSpeedTextBox_Error(object sender, ValidationErrorEventArgs e)
		{
			if (Validation.GetHasError(shutterSpeedTextBox))
				shutterSpeedPowerToolTip.Error = INVALID_FORM_ERROR;
			else
				shutterSpeedPowerToolTip.Error = "";
		}

		#endregion




		#region expander properties

		/// <summary>
		/// Get or set whether the general expander is expaned
		/// </summary>
		public bool IsGeneralExpanded
		{
			get { return (bool)GetValue(IsGeneralExpandedProperty); }
			set { SetValue(IsGeneralExpandedProperty, value); }
		}

		/// <summary>
		/// Identifies the IsGeneralExpanded dependency property
		/// </summary>
		public static readonly DependencyProperty IsGeneralExpandedProperty =
			DependencyProperty.Register("IsGeneralExpanded", typeof(bool), 
			typeof(ImageTagView), new UIPropertyMetadata(true));


		/// <summary>
		/// Get or set whether the description expander is expaned
		/// </summary>
		public bool IsDescriptionExpanded
		{
			get { return (bool)GetValue(IsDescriptionExpandedProperty); }
			set { SetValue(IsDescriptionExpandedProperty, value); }
		}

		/// <summary>
		/// Identifies the IsDescriptionExpanded dependency property
		/// </summary>
		public static readonly DependencyProperty IsDescriptionExpandedProperty =
			DependencyProperty.Register("IsDescriptionExpanded", typeof(bool),
			typeof(ImageTagView), new UIPropertyMetadata(true));


		/// <summary>
		/// Get or set whether the datetime expander is expaned
		/// </summary>
		public bool IsDateTimeExpanded
		{
			get { return (bool)GetValue(IsDateTimeExpandedProperty); }
			set { SetValue(IsDateTimeExpandedProperty, value); }
		}

		/// <summary>
		/// Identifies the IsDateTimeExpanded dependency property
		/// </summary>
		public static readonly DependencyProperty IsDateTimeExpandedProperty =
			DependencyProperty.Register("IsDateTimeExpanded", typeof(bool),
			typeof(ImageTagView), new UIPropertyMetadata(true));


		/// <summary>
		/// Get or set whether the picture condition expander is expaned
		/// </summary>
		public bool IsPictureConditionsExpanded
		{
			get { return (bool)GetValue(IsPictureConditionsExpandedProperty); }
			set { SetValue(IsPictureConditionsExpandedProperty, value); }
		}

		/// <summary>
		/// Identifies the IsDateTimeExpanded dependency property
		/// </summary>
		public static readonly DependencyProperty IsPictureConditionsExpandedProperty =
			DependencyProperty.Register("IsPictureConditionsExpanded", typeof(bool),
			typeof(ImageTagView), new UIPropertyMetadata(true));


		#endregion




	}
}
